package damas.ReglasDeAvances;

import java.util.LinkedList;
import java.util.List;

import utils.Pair;
import damas.modelo.DamasEstado;
import framework.IRule;

/**
 * @author Sin codigo Esta regla de avance, avanza comiendo hacia abajo, tanto
 *         para izquierda como para derecha, siempre que sea posible
 * 
 */
public class AvanzaComiendoHaciaAbajo implements IRule<DamasEstado> {

	@Override
	public boolean isApplicable(DamasEstado estado) {
		return (estado.isMax() && (!estado.getRojasObligadasAComer().isEmpty() || !estado
				.getRojasDamasObligadasAComer().isEmpty()))
				|| (estado.isMin() && !estado.getNegrasDamasObligadasAComer()
						.isEmpty());
	}

	// ya se que tengo alguna en la lista de obligadas a comer
	@Override
	public List<DamasEstado> apply(DamasEstado estado) {
		LinkedList<DamasEstado> newEstados = new LinkedList<DamasEstado>();
		int miColor = estado.isMax() ? estado.ROJA : estado.NEGRA;
		LinkedList<Pair<Integer, Integer>> obligadasAComer = new LinkedList<Pair<Integer, Integer>>();

		Pair<Integer, Integer> avAbajoIzq;
		Pair<Integer, Integer> avAbajoDer;
		int y;
		int x;
		// cargo mi lista de fichas a mover
		if (miColor == estado.ROJA) {
			if (estado.genereMovidaObligatoria) {
				obligadasAComer.add(estado.inicioObligatorio);
			} else {

				obligadasAComer = (LinkedList<Pair<Integer, Integer>>) estado
						.getRojasObligadasAComer();
				obligadasAComer.addAll(estado.getRojasDamasObligadasAComer());
			}
		} else {
			if (estado.genereMovidaObligatoria) {
				obligadasAComer.add(estado.inicioObligatorio);
			} else {
				obligadasAComer = (LinkedList<Pair<Integer, Integer>>) estado
						.getNegrasDamasObligadasAComer();
			}
		}
		boolean useElClon = false;
		for (Pair<Integer, Integer> pair : obligadasAComer) {
			DamasEstado newEstado = estado.clone();
			y = pair.getFirstElem();
			x = pair.getSecondElem();
			avAbajoDer = new Pair<Integer, Integer>(y + 2, x + 2);
			avAbajoIzq = new Pair<Integer, Integer>(y + 2, x - 2);

			// la casilla esta en el tablero && tengo para comer
			if (newEstado.esCasillaValida(avAbajoDer)
					&& !newEstado.hayFichaEnLaCasilla(avAbajoDer)
					&& newEstado.esPosibleComerAbajoDer(pair, avAbajoDer,
							miColor)) {
				newEstado.mover(pair, avAbajoDer);
				newEstado.genereMovidaObligatoria = newEstado
						.tieneComidaAlcanzable(avAbajoDer);
				if (miColor == estado.ROJA) {
					newEstado.rojaComioEncadenada = newEstado.genereMovidaObligatoria;
				} else {
					newEstado.negraComioEncadenada = newEstado.genereMovidaObligatoria;
				}
				// obliga a usar esta pos para el proximo movimiento
				if (newEstado.genereMovidaObligatoria) {
					newEstado.inicioObligatorio = avAbajoDer;
				}
				newEstados.add(newEstado);// meto el nuevo estado
				useElClon = true;
			}

			if (useElClon) {
				newEstado = estado.clone();
			}
			// la casilla esta en el tablero && tengo para comer
			if (newEstado.esCasillaValida(avAbajoIzq)
					&& !newEstado.hayFichaEnLaCasilla(avAbajoIzq)
					&& newEstado.esPosibleComerAbajoIzq(pair, avAbajoIzq,
							miColor)) {
				newEstado.mover(pair, avAbajoIzq);
				newEstado.genereMovidaObligatoria = newEstado
						.tieneComidaAlcanzable(avAbajoIzq);
				
				if (miColor == estado.ROJA) {
					newEstado.rojaComioEncadenada = newEstado.genereMovidaObligatoria;
				} else {
					newEstado.negraComioEncadenada = newEstado.genereMovidaObligatoria;
				}

				// obliga a usar esta pos para el proximo movimiento
				if (newEstado.genereMovidaObligatoria) {
					newEstado.inicioObligatorio = avAbajoIzq;
				}

				newEstados.add(newEstado);// meto el nuevo estado
			}
		}// end for

		return newEstados;

	}
}
